package com.hyt.it.ogt.ks.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.hyt.it.ogt.ks.config.ConfigManager;
import com.hyt.it.ogt.ks.model.vo.paper.PItemDTO;
import com.hyt.it.ogt.ks.model.vo.paper.PTopicDTO;

import lombok.extern.slf4j.Slf4j;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

/**
 * @author wuyingge
 * @ClassName EnCacheUtil.java
 * @Description encache 二级缓存使用简单工具类，可跟据业务需要增加方法
 * @createTime 2021年10月18日 08:49:00
 */
@Component
@Slf4j
public class EnCacheUtil {

    @Resource(name = "paper_cache")
    private Cache paperCache;
    
    @Resource(name = "paper_translate_cache")
    private Cache paperTranslateCache;
    
    @Resource
    private RedisTemplate redisTemplate;
    
    @Resource(name = "exam_info_cache")
    private Cache examInfoCache;
    @Resource
    private ConfigManager configManager;


    /**
     * 将考试配置信息放入encache
     * @param key
     * @param data
     * @param expire
     * @return
     */
    public Boolean putExamInfoToCache(String key, String data,String expire){
        try {
            //把一个元素添加到Cache中
            Element exam = new Element(key,data,configManager.getExamCacheExpire(),configManager.getExamCacheExpire());
            examInfoCache.put(exam);
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("将考试配置信息存入encache缓存失败，key:【{}】,value：【{}】,异常信息为:【{}】",key,data,e);
            return Boolean.FALSE;
        }
    }

    /**
     * 将考试配置信息移出encache
     * @param key
     * @return
     */
    public Boolean removeExamInfoToCache(String key){
        try {
            return examInfoCache.remove(key);
        } catch (Exception e){
            log.error("将考试配置信息移出encache缓存失败，key:【{}】,异常信息为:【{}】",key,e);
            return Boolean.FALSE;
        }
    }

    /**
     * 从cache中获取对象  注意自己判断空
     * @param key
     * @return
     */
    public String getExamInfoFromCache(String key){
        try {
            Element element = examInfoCache.get(key);
            if(Objects.nonNull(element) && Objects.nonNull(element.getObjectValue())){
                return String.valueOf(element.getObjectValue());
            }
            return null;
        } catch (Exception e){
            log.error("将考试配置信息移出encache缓存失败，key:【{}】,异常信息为:【{}】",key,e);
            return null;
        }
    }
    /**
     * 放入试卷(包括题目，大题，小题及选项相关信息的缓存)，  encache - > redis
     * @param key : redis的key
     * @return : 是否成功
     */
    public Boolean putPaperInfoCache(String key,String data,Long expire){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            //判断encache是否有
            Boolean isExists = paperCache.isElementInMemory(key);
            if(Objects.equals(Boolean.TRUE,isExists)){
                return Boolean.TRUE;
            }
            //把一个元素添加到Cache中
            Element paper = new Element(key,data);
            paperCache.put(paper);
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("数据存入encache缓存失败，key:【{}】,value：【{}】,异常信息为:【{}】",key,data,e);
            return Boolean.FALSE;
        }
    }

    public Boolean putAndSetPaperInfoCache(String key,String data){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            //判断encache是否有
            Boolean isExists = paperCache.isElementInMemory(key);
            if(Objects.equals(Boolean.TRUE,isExists)){
                paperCache.remove(key);
            }
            //把一个元素添加到Cache中
            Element paper = new Element(key,data);
            paperCache.put(paper);
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("数据存入encache缓存失败，key:【{}】,value：【{}】,异常信息为:【{}】",key,data,e);
            return Boolean.FALSE;
        }
    }

    /**
     * 获取缓存 ---- encache --> redis --- > encache ---> return
     * @param key
     * @return
     */
    public String getPaperInfoCache(String key){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            //1:判断encache是否有
            Element dataElement = paperCache.get(key);
            if(Objects.isNull(dataElement) || Objects.isNull(dataElement.getObjectValue())){
                //2:先去redis中取
                String paperInfoString = (String) redisTemplate.opsForValue().get(key);
                if (StringUtils.isNotBlank(paperInfoString) && !"null".equalsIgnoreCase(paperInfoString)) {
                    //存入encache中
                    Element paper = new Element(key,paperInfoString);
                    paperCache.put(paper);
                    return paperInfoString;
                }
                return "null";
            }
            return String.valueOf(dataElement.getObjectValue());
        } catch (Exception e){
            log.error("获取数据encache缓存失败，key:【{}】,异常信息为:【{}】",key,e);
            return "null";
        }
    }

    /**
     * 保存试卷的主题 或 小题
     * @param key
     * @param data map结构
     * @param expire
     * @return
     */
    public Boolean putPaperTopicItemCache(String key, String data,Long expire){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            Element element = new Element(key,data);
            paperCache.put(element);
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("数据存入encache缓存失败，key:【{}】,数据为:【{}】异常信息为:【{}】",key,data,e);
            return Boolean.FALSE;
        }
    }

    /**
     * 获取试卷的topic结构
     * @param key
     * @return
     */
    public Map<String, PTopicDTO> getPaperTopiCache(String key){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            //1:判断encache是否有
            Element dataElement = paperCache.get(key);
            if(Objects.isNull(dataElement) || Objects.isNull(dataElement.getObjectValue())){
                //2:先去redis中取
                Map<String, PTopicDTO> map = redisTemplate.opsForHash().entries(key);
                if (Objects.nonNull(map) && !map.isEmpty()) {
                    Element element = new Element(key,JSON.toJSONString(map));
                    paperCache.put(element);
                    return map;
                }
                return null;
            }
            String mapStr = String.valueOf(dataElement.getObjectValue());
            HashMap<String,PTopicDTO> topicMap =
                    JSON.parseObject(mapStr,new TypeReference<HashMap<String,PTopicDTO>>() {});
            return topicMap;
        } catch (Exception e){
            log.error("获取数据encache缓存失败，key:【{}】,异常信息为:【{}】",key,e);
            return null;
        }
    }

    /**
     * 获取试卷的topic结构
     * @param key
     * @return
     */
    public Map<String, PItemDTO> getPaperItemCache(String key){
        try {
            //获取指定Cache
            //Cache paperCache = cacheManager.getCache(CACHE_NAME);
            //1:判断encache是否有
            Element dataElement = paperCache.get(key);
            if(Objects.isNull(dataElement) || Objects.isNull(dataElement.getObjectValue())){
                //2:先去redis中取
                Map<String, PItemDTO> map = redisTemplate.opsForHash().entries(key);
                if (Objects.nonNull(map) && !map.isEmpty()) {
                    Element element = new Element(key,JSON.toJSONString(map));
                    paperCache.put(element);
                    return map;
                }
                return null;
            }
            String mapStr = String.valueOf(dataElement.getObjectValue());
            HashMap<String,PItemDTO> topicMap =
                    JSON.parseObject(mapStr,new TypeReference<HashMap<String,PItemDTO>>() {});
            return topicMap;
        } catch (Exception e){
            log.error("获取数据encache缓存失败，key:【{}】,异常信息为:【{}】",key,e);
            return null;
        }
    }

    /**
     * 清理paperInfo相关的key
     * @return
     */
    public Boolean clearPaperInfoCache(){
        try {
            paperCache.removeAll();
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("清除ehcache二级paperInfo缓存操作失败:",e);
            return Boolean.FALSE;
        }
    }

    /**
     * 获取试卷翻译信息放到 encache  --》 redis  -->kwClient
     * @return  返回为null则说明encache中没有
     */
    public HashMap<String, String> getPaperTranslateCache(String key) {
        Element element = paperTranslateCache.get(key);
        if(Objects.isNull(element)){
            return null;
        }
        String mapStr = String.valueOf(element.getObjectValue());
        HashMap<String,String> translateMap = JSON.parseObject(mapStr,new TypeReference<HashMap<String,String>>(){});
        return translateMap;
    }

    /**
     * 放入缓存encache
     * @param key
     * @param data
     * @return
     */
    public Boolean putPaperTransateToEncache(String key,String data){
        try {
            Element element = new Element(key,data);
            paperCache.put(element);
            return Boolean.TRUE;
        } catch (Exception e){
            log.error("数据存入encache缓存失败，key:【{}】,数据为:【{}】异常信息为:【{}】",key,data,e);
            return Boolean.FALSE;
        }
    }

    /**
     * 根据key来清除缓存
     * @param key
     * @return
     */
    public Boolean clearPaperTransateFromEncache(String key){
        Boolean isExists = paperTranslateCache.isElementInMemory(key);
        if(Objects.equals(Boolean.FALSE,isExists)){
            return Boolean.TRUE;
        }
        return paperTranslateCache.remove(key);
    }

}
